import { CryptoUtility } from "./CryptoUtility";

export class Cryptogram
{
    private static GUID_KEY_LEN:number = 96;
    private static SN_KEY_LEN:number = 96;
    // private static CHECK_IDs:Array<number> = [0x6f, 0x2e, 0x5f, 0x29, 0x6a, 0x70, 0x35, 0x26 ];
	// public static HEADER_LEN:number = 20;

    //<summary>-----------------------------------------------------------------------------
    // Web数据加解密
    //</summary>-----------------------------------------------------------------------------
    public static EncodeWebData(data:object,sn:number=1):string
    {
        var dataStr:string = "";
        if(typeof data === "string")dataStr = data;
        else dataStr = JSON.stringify(data);
        
        var SNKey:string = CryptoUtility.GenSNKey(sn);
        var GUIDKey:string = CryptoUtility.GenGuidKey(String(0));

        var key:string = CryptoUtility.GenDynamicKey(SNKey, GUIDKey);
        dataStr = CryptoUtility.EncodeAESString(dataStr,key);
        dataStr += GUIDKey + SNKey;
        var bytes:CryptoJS.lib.WordArray = CryptoUtility.GetBytes(dataStr);
        bytes = CryptoUtility.CompressBytes(bytes);
        return CryptoUtility.GetBase64String(bytes);
    }

    public static DecodeWebData(data:string):string
    {
        var bytes:CryptoJS.lib.WordArray = CryptoUtility.GetBase64Byte(data);
        bytes = CryptoUtility.Decompress(bytes);
        data = CryptoUtility.GetString(bytes);
        // 取得資料
        var encryptData:string = data.substr(0, data.length - this.SN_KEY_LEN - this.GUID_KEY_LEN);
        // 取得 Guid Key
        var GUIDKey:string = data.substr(encryptData.length, this.GUID_KEY_LEN);


        // 取得 SN Key
        var SNKey:string = data.substr(encryptData.length + this.GUID_KEY_LEN, this.SN_KEY_LEN);
        // 產生 Final Key
        var key:string = CryptoUtility.GenDynamicKey(SNKey, GUIDKey);
        // console.log("SNKey:",SNKey);
        // console.log("GUIDKey:",GUIDKey);
        return CryptoUtility.DecodeAESString(encryptData,key);
    }

    //<summary>-----------------------------------------------------------------------------
    // Socket 数据加解密
    //</summary>-----------------------------------------------------------------------------
    public static EncodeSocketData(packetID:number,data:any,isNeedCompress:boolean,CDataKey:string = null,sn:number = 1):any
    {
        if(CDataKey)
        {
            data = CryptoUtility.EncodeAESByte(data,CDataKey);
            if(isNeedCompress)data = CryptoUtility.CompressBytes(data);
            return this.EncodeJointHeader(packetID, data);
        }else
        {
            if(isNeedCompress)data = CryptoUtility.CompressBytes(data,true);
            // 加密
            var SNKey:string = CryptoUtility.GenSNKey(sn);
            var GUIDKey:string = CryptoUtility.GenGuidKey();
            // var SNKey:string = "c4ca4238a0b923820dcc509a6f75849b6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b";
            // var GUIDKey:string = "b88ce602de410bbedfab04e30e5a2f5b0a687960239b824ea45ca29d4eb2338ecfcd208495d565ef66e7dff9f98764da";//CryptoUtility.GenGuidKey();
            var key:string = CryptoUtility.GenDynamicKey(SNKey, GUIDKey);
            data = CryptoUtility.EncodeAESByte(CryptoUtility.Byte2WordArray(data),key);
            // Base64 第一次
            var base64:string = CryptoUtility.GetBase64String(data) + GUIDKey + SNKey;
            data = CryptoUtility.GetBytes(base64);
            // Base64 第二次
            base64 = CryptoUtility.GetBase64String(data);
            data = CryptoUtility.GetBytes(base64);
            return this.EncodeJointHeader(packetID, data);
        }
    }
    public static EncodeJointHeader(packetID:number,data:any):any
    {
        return CryptoUtility.Word2ByteArray(data,true,packetID);
    }

    //////////////////////////////////////////////////////////////////////////////

    // public static GetSocketDatas(bytes:any):any[]
    // {
    //     var msgLen:any = this.GetDecodeMsgLength(bytes);
    //     var datas:any[] = msgLen!=null?[]:null;
    //     while(msgLen!=null)
    //     {
    //         datas.push(CryptoUtility.SpliteBytes(bytes,0,msgLen));
    //         msgLen = this.GetDecodeMsgLength(bytes);
    //     }
    //     return datas;
    // }
    // /**
    //  * 是否为可解密数据
    //  */        
    // public static GetDecodeMsgLength(bytes:any):any
    // {
    //     // 数据长度大于消息的头长度
    //     if (bytes.length> this.HEADER_LEN)
    //     {
    //         // 先找包头
    //         var isFindHeader:boolean = this.FindPacketHeader(bytes,0);
    //         if(isFindHeader)
    //         {
    //             var packetID:number = this.GetPacketID(bytes);
    //             // 读取当前消息包的长度
    //             var msgLength:number = this.GetPackageLength(bytes, 0);
    //             var totalLen:number = msgLength+this.HEADER_LEN;
    //             // 消息长度不为0，并且当前可读的消息长度去掉消息头还有足够的数据
    //             if (bytes.length >= totalLen)return totalLen;
    //         }
    //     }
    //     return null;
    // }
    // 解密Socket数据
    public static DecodeSocketData(data:any,isGenDynamicKey:boolean,isNeedUnCompress:boolean,CDataKey:string = null):any
    {
        var packetID:number = CryptoUtility.SpliteBytes(data,0,1)[0];
        if (!isGenDynamicKey)
        {
            if(CDataKey!=null&&CDataKey!="")
            {

                data = CryptoUtility.ConvertWordArray(data);
                var bytes1:any = CryptoUtility.DecodeAESByte(data,CDataKey);
                if (isNeedUnCompress && bytes1 != null) bytes1 = CryptoUtility.Decompress(bytes1);
                return bytes1;
            }else return data;
        }else
        {
            data = CryptoUtility.ConvertWordArray(data);
            // 读取数据
            var msgData:string = CryptoUtility.GetString(data);
            var bytes:any = CryptoUtility.GetBase64Byte(msgData);
            msgData = CryptoUtility.GetString(bytes);
            // 取得資料
            var EncryptData:string = msgData.substr(0, msgData.length - this.SN_KEY_LEN - this.GUID_KEY_LEN);
            // 取得 Guid Key
            var GuidKey:string = msgData.substr(EncryptData.length, this.GUID_KEY_LEN);
            // 取得 SN Key
            var SNKey:string = msgData.substr(EncryptData.length + this.GUID_KEY_LEN, this.SN_KEY_LEN);
            // 產生 Final Key
            var Key:string = CryptoUtility.GenDynamicKey(SNKey, GuidKey);
            bytes = CryptoUtility.DecodeAESByte(CryptoUtility.GetBase64Byte(EncryptData),Key);
            if (isNeedUnCompress) bytes = CryptoUtility.Decompress(bytes);
            return bytes;
        }
    }
    public static GetPacketID(data:any):number{return data[0];}
    // /// <summary>
    // /// 查找包头
    // /// </summary>
    // private static FindPacketHeader(bytes:any,offset:number):boolean
    // {
    //     for (var i:number = 0; i < this.CHECK_IDs.length; i++)
    //     {
    //         if (this.CHECK_IDs[i] != bytes[offset + i])
    //             return false;
    //     }
    //     return true;
    // }
    // /// <summary>
    // /// 从消息中获取到包的长度
    // /// </summary>
    // private static GetPackageLength(data:any,proccessIdx:number):number
    // {
    //     var num1:number = data[proccessIdx + 12] << 56;
    //     var num2:number = data[proccessIdx + 13] << 48;
    //     var num3:number = data[proccessIdx + 14] << 40;
    //     var num4:number = data[proccessIdx + 15] << 32;
    //     var num5:number = data[proccessIdx + 16] << 24;
    //     var num6:number = data[proccessIdx + 17] << 16;
    //     var num7:number = data[proccessIdx + 18] << 8;
    //     var num8:number = data[proccessIdx + 19] & 0xFFFF;
    //     return num1 + num2 + num3 + num4 + num5 + num6 + num7 + num8;
    // }
    // /// <summary>
    // /// 从数据中获取检查码
    // /// </summary>
    // private static GetCheckCode(data:any):number
    // {
    //     var num5:number = data[8] << 24;
    //     var num6:number = data[9] << 16;
    //     var num7:number = data[10] << 8;
    //     var num8:number = data[11] & 0xFF;
    //     return num5 + num6 + num7 + num8;
    // }
}